/**
 * 
 */
package edu.gtcfla.km.appmodules.service.impl;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.vsg.biz.BusinessOperationException;
import org.vsg.common.model.algstrategy.GenTreeModelBuilder;
import org.vsg.common.model.json.TreeNode;
import org.vsg.search.api.criterion.PaginationCriteria;
import org.vsg.search.api.page.PaginationException;

import edu.gtcfla.km.Category;
import edu.gtcfla.km.FileFormat;
import edu.gtcfla.km.Knowledge;
import edu.gtcfla.km.UploadFile;
import edu.gtcfla.km.UserGroup;
import edu.gtcfla.km.UserGroupPermission;
import edu.gtcfla.km.UserPermission;
import edu.gtcfla.km.appmodules.service.UploadFileService;
import edu.gtcfla.km.appmodules.vo.UploadFileFormVO;
import edu.gtcfla.km.appmodules.vo.UploadFileListViewVO;
import edu.gtcfla.km.model.UploadFileD;
import edu.gtcfla.km.repositories.FileFormatRepo;
import edu.gtcfla.km.repositories.KnowledgeRepo;
import edu.gtcfla.km.repositories.UploadFileRepo;
import edu.gtcfla.km.repositories.UserGroupPermissionRepo;
import edu.gtcfla.km.repositories.UserGroupRepo;
import edu.gtcfla.km.repositories.UserPermissionRepo;
import edu.gtcfla.km.security.api.SubjectManager;

/**
 * @author vison
 *
 */
public class UploadFileServiceI implements UploadFileService {

	@Autowired(required=false)
	private UploadFileRepo<UploadFile,String> uploadFileRepo;
	
	@Autowired(required=false)
	private edu.gtcfla.km.repositories.CategoryRepo<Category,String> categoryRepo;

	
	@Autowired(required=false)	
	private UserGroupRepo<UserGroup , String> userGroupRepo;	
	
	@Autowired(required=false)
	private KnowledgeRepo knowledgeRepo;
	
	@Autowired(required=false)
	private FileFormatRepo fileFormatRepo;
	
	@Autowired(required = false)
	private SubjectManager subjectManager;
	
	@Autowired(required=false)	
	private UserPermissionRepo<UserPermission,Serializable> userPermissionRepo;
	

	@Autowired(required=false)	
	private UserGroupPermissionRepo<UserGroupPermission , String> usergroupPermRepo;
		
	
	/* (non-Javadoc)
	 * @see edu.gtclfla.km.appmodules.service.UploadFileService#pageUploadFiles(org.vsg.search.api.criterion.PaginationCriteria)
	 */
	@Override
	public Set<UploadFileListViewVO> listUploadFiles(
			PaginationCriteria criteria) throws BusinessOperationException,
			PaginationException {
		// TODO Auto-generated method stub
		
		String docId = (String)criteria.getValue("docId");
		
		String categoryId = (String)criteria.getValue("categoryId");
		
		String fileformat = (String)criteria.getValue("fileFormat");

		
		if (fileformat != null && fileformat.equals("all")) {
			fileformat = null;
		}
		
		Iterable<UploadFile>  uploadFileIter = null;
		
		if (docId != null) {
			// --- file all doc id
			uploadFileIter = uploadFileRepo.findAllByKnowledgeAndFileFormat( docId  , fileformat);
		} else {
			uploadFileIter = uploadFileRepo.findAllByCate(categoryId, fileformat); 
		}
		
		
		
		Set<UploadFileListViewVO> upFileListView = new LinkedHashSet<UploadFileListViewVO>();
		
		for (UploadFile uf : uploadFileIter) {
			
			UploadFileListViewVO ufv = new UploadFileListViewVO();
			ufv.setId( uf.getId() );
			ufv.setName( uf.getTitle() );
			ufv.setFileName( uf.getFileName() );
			ufv.setExt( uf.getExt() );
	
			
			// --- set the url ---
			String ext = uf.getExt();

			
			if (ext != null) {
				StringBuilder strBuilder = new StringBuilder("../..");
				// --- check stand file format ---
				if (".jpg".contains(ext) 
					|| ".gif".contains(ext)
					|| ".png".contains(ext)
				) {
					strBuilder.append("/data/image?");					
					strBuilder.append("fileName="+ufv.getFileName() );
					strBuilder.append( "");
					ufv.setExtformat("img");
					ufv.setUrl( strBuilder.toString() );
					ufv.setBigPicUrl( strBuilder.toString());						
				} 
				// --- get for other attachment file 
				else if ( ".doc".contains(ext) || ".docx".contains(ext)
						|| ".xls".contains(ext) || ".xlsx".contains(ext)
						|| ".zip".contains(ext) || ".rar".contains(ext) ) {
					
	 				// --- not format support ---
					if (".doc".contains(ext) || ".docx".contains(ext) ) {
						strBuilder.append("/data/images/icon-word.png");
						ufv.setExtformat(ext);
						ufv.setUrl( strBuilder.toString() );
					}
					else if (".xls".contains(ext) || ".xlsx".contains(ext) ) {
						strBuilder.append("/data/images/icon-excel.png");
						ufv.setExtformat(ext);
						ufv.setUrl( strBuilder.toString() );
					}
					else if (".zip".contains(ext) || ".rar".contains(ext) ) {
						strBuilder.append("/data/images/icon-zip.png");
						ufv.setExtformat(ext);
						ufv.setUrl( strBuilder.toString() );
					}
					else {
						strBuilder.append("/data/images/icon-text.png");
						ufv.setExtformat(ext);
						ufv.setUrl( strBuilder.toString() );
					}
					ufv.setBigPicUrl( "../../data/file?docId="+uf.getId());
				}
				// --- media ---
				else if ( ".avi .asf .mp4 .wmv".contains(ext) ) {
					strBuilder.append("/data/images/icon-text.png");
					ufv.setExtformat(ext);
					ufv.setUrl( strBuilder.toString() );
					ufv.setBigPicUrl( "../../data/media?docId="+uf.getId());
				}


			} else {
				StringBuilder strBuilder = new StringBuilder("../..");
				strBuilder.append("/data/images/icon-text.png");
				
				ufv.setExtformat("oth");
				ufv.setUrl( strBuilder.toString() );
				ufv.setBigPicUrl( "../../data/file?docId="+uf.getId()  );	
			}
			
			upFileListView.add( ufv );
		}

		
		return upFileListView;
	}

	@Override
	public void addUploadFile(UploadFileFormVO uploadFileView)
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		
		UploadFile entity = uploadFileView.getEntity();

		String categoryId = uploadFileView.getCategoryId();
		if (categoryId != null && !categoryId.trim().equals("") && !categoryId.trim().equals("root")) {
			Category cate = categoryRepo.findOne( categoryId );
			entity.setCategory( cate );
		} else {
			entity.setCategory(null);

		}		
		
		
		Map<String,FileFormat>  allSupportFileFormat = fileFormatRepo.findAllMap();

		for (FileFormat ff : allSupportFileFormat.values() ) {
			String suffix = ff.getSuffix();
			if (suffix.contains( entity.getExt() ) ) {
				UploadFileD ufd = (UploadFileD)entity;
				ufd.addFileFormat( ff );
			}
		}		
		
		String currAccountId = subjectManager.getCurrentAccountId();
		Calendar cale = Calendar.getInstance();
		entity.setReleasedUserId(currAccountId );
		entity.setReleasedDate( cale.getTime() );
		
		UserGroup userGroup = userGroupRepo.findFirstOneByUserId( currAccountId );
		if (userGroup != null) {
			entity.setUserGroupId( userGroup.getId() );
		}
		
		uploadFileRepo.save( entity );
		
	}

	@Override
	public void addUploadfileToDocId(UploadFileFormVO uploadFileView, String docId) {
		// TODO Auto-generated method stub

		UploadFile entity = uploadFileView.getEntity();
		
		String currAccountId = subjectManager.getCurrentAccountId();
		Calendar cale = Calendar.getInstance();
		entity.setReleasedUserId(currAccountId );
		entity.setReleasedDate( cale.getTime() );

		UserGroup userGroup = userGroupRepo.findFirstOneByUserId( currAccountId );
		if (userGroup != null) {
			entity.setUserGroupId( userGroup.getId() );
		}
		
		
		Knowledge knowledge = knowledgeRepo.findOne( docId);
		entity.setCategory( knowledge.getCategory() );
		
		
		Map<String,FileFormat>  allSupportFileFormat = fileFormatRepo.findAllMap();
		
		for (FileFormat ff : allSupportFileFormat.values() ) {
			String suffix = ff.getSuffix();
			if (suffix.contains( entity.getExt() ) ) {
				UploadFileD ufd = (UploadFileD)entity;
				ufd.addFileFormat( ff );
			}
		}
		
		//uploadFileRepo.save( entity );
		
		uploadFileRepo.bindingAttacthmentToDoc(entity , knowledge);
		
		// ---- binding format ---
		
	}

	@Override
	public UploadFile loadUploadFile(String fileId) {
		// TODO Auto-generated method stub
		UploadFile uploadFile = uploadFileRepo.findOne( fileId );
		
		return uploadFile;

	}

	@Override
	public Set<UploadFileListViewVO> listUploadFilesWithCurrentAccount(
			PaginationCriteria criteria) throws BusinessOperationException,
			PaginationException {
		
		
		String docId = (String)criteria.getValue("docId");
		
		String categoryId = (String)criteria.getValue("categoryId");
		
		String fileformat = (String)criteria.getValue("fileFormat");

		
		if (fileformat != null && fileformat.equals("all")) {
			fileformat = null;
		}
		
		Iterable<UploadFile>  uploadFileIter = null;
		
		if (docId != null) {
			// --- file all doc id
			uploadFileIter = uploadFileRepo.findAllByKnowledgeAndFileFormat( docId  , fileformat);
		} else {
			
			// --- get files by category id ---
			uploadFileIter = getFileByCategoryId(categoryId, fileformat);
			
		}
		
		
		
		Set<UploadFileListViewVO> upFileListView = new LinkedHashSet<UploadFileListViewVO>();
		
		for (UploadFile uf : uploadFileIter) {
			
			UploadFileListViewVO ufv = new UploadFileListViewVO();
			ufv.setId( uf.getId() );
			ufv.setName( uf.getTitle() );
			ufv.setFileName( uf.getFileName() );
			ufv.setExt( uf.getExt() );
	
			
			// --- set the url ---
			String ext = uf.getExt();
			if (ext != null) {
				StringBuilder strBuilder = new StringBuilder("../..");
				// --- check stand file format ---
				if (".jpg".contains(ext) 
					|| ".gif".contains(ext)
					|| ".png".contains(ext)
				) {
					strBuilder.append("/data/image?");					
					strBuilder.append("fileName="+ufv.getFileName() );
					strBuilder.append( "");
					ufv.setExtformat("img");
					ufv.setUrl( strBuilder.toString() );
					ufv.setBigPicUrl( strBuilder.toString());						
				} 
				// --- get for other attachment file 
				else if ( ".doc".contains(ext) || ".docx".contains(ext)
						|| ".xls".contains(ext) || ".xlsx".contains(ext)
						|| ".zip".contains(ext) || ".rar".contains(ext) ) {
					
	 				// --- not format support ---
					if (".doc".contains(ext) || ".docx".contains(ext.toLowerCase()) ) {
						strBuilder.append("/data/images/icon-word.png");
						ufv.setExtformat(ext);
						ufv.setUrl( strBuilder.toString() );
					}
					else if (".xls".contains(ext) || ".xlsx".contains(ext.toLowerCase()) ) {
						strBuilder.append("/data/images/icon-excel.png");
						ufv.setExtformat(ext);
						ufv.setUrl( strBuilder.toString() );
					}
					else if (".zip".contains(ext) || ".rar".contains(ext.toLowerCase()) ) {
						strBuilder.append("/data/images/icon-zip.png");
						ufv.setExtformat(ext);
						ufv.setUrl( strBuilder.toString() );
					}
					else {
						strBuilder.append("/data/images/icon-text.png");
						ufv.setExtformat(ext);
						ufv.setUrl( strBuilder.toString() );
					}
					ufv.setBigPicUrl( "../../data/file?docId="+uf.getId());
				}
				// --- media ---
				else if ( ".avi .asf .mp4 .wmv .mpg ".contains(ext.toLowerCase()) ) {
					strBuilder.append("/data/images/icon-text.png");
					ufv.setExtformat(ext);
					ufv.setUrl( strBuilder.toString() );
					ufv.setBigPicUrl( "../../data/media?docId="+uf.getId());
				}
				


			} else {
				StringBuilder strBuilder = new StringBuilder("../..");
				strBuilder.append("/data/images/icon-text.png");
				
				ufv.setExtformat("oth");
				ufv.setUrl( strBuilder.toString() );
				ufv.setBigPicUrl( "../../data/file?docId="+uf.getId()  );	
			}
			
			upFileListView.add( ufv );
		}

		
		return upFileListView;

		
		
		
	}
	
	
	private Iterable<UploadFile> getFileByCategoryId(String categoryId , String fileformat) {
		String accountId = subjectManager.getCurrentAccountId();

		// --- get current group current permission --
		UserGroup userGroup = userGroupRepo.findFirstOneByUserId(accountId);		
		
		// --- get current user group from account ---
		
		// --- usergroup perms
		Map<String, UserGroupPermission>  usergroupPerms = new LinkedHashMap<String , UserGroupPermission>();
		if (userGroup != null) {
			usergroupPerms = this.usergroupPermRepo.findUserGroupPermissionForCategories(userGroup.getId());
		}
		
		// --- get user permission suppport ---
		Map<String, UserPermission>  supportedUserPermMap =  userPermissionRepo.findUserPermissionForCategories( accountId );
		
		
		UserPermission supportUserPerm = supportedUserPermMap.get( categoryId );
		UserGroupPermission supportUserGroupPerm = usergroupPerms.get( categoryId );
		
		// --- get the user perm ---
		if (supportUserPerm == null  && supportUserGroupPerm == null) {

			return new LinkedHashSet();
		}

		
		Map<String, Category>  categoryMap =  categoryRepo.findAllMap() ;

		// --- find the submenu ---
		GenTreeModelBuilder genTreeBuilder = new GenTreeModelBuilder( categoryMap );
		genTreeBuilder.generate();
		
		Map<String , TreeNode> treeMap = genTreeBuilder.getResultMap();
		
		TreeNode currentCate = treeMap.get( categoryId.toString() );

		// --- get all category ---
		Set<String> allCateIds = new LinkedHashSet<String>();
		findAllCategoryIds(currentCate , allCateIds);
		
		// --- add condition ---
		String userGroupId = null;
		if (userGroup != null) {
			userGroupId = userGroup.getId();
		}
		
		Iterable<UploadFile> uploadFiles =  uploadFileRepo.findAllByCateAndFileFormat(  allCateIds ,  accountId , userGroupId ,fileformat);
		
		return  uploadFiles;
	}
	
	
	private void findAllCategoryIds(TreeNode treeNode , Set<String> allIds) {
		allIds.add( treeNode.getId() );
		
		Collection<TreeNode> coll = treeNode.getChildren();
		if ( coll != null && !coll.isEmpty() ) {
			for (TreeNode subTreeNode : coll) {
				findAllCategoryIds(subTreeNode , allIds);
			}
		}

		
	}
		
	

}
